package net.maku.module.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import net.maku.framework.common.utils.ApiSignUtils;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.common.utils.Result;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.framework.security.user.SecurityUser;
import net.maku.framework.security.user.UserDetail;
import net.maku.module.dao.AgCategoryPermissionDao;
import net.maku.module.dao.AgContentDao;
import net.maku.module.entity.*;
import net.maku.module.service.AgApproveService;
import net.maku.module.service.AgContentService;
import net.maku.module.util.UrlReplaceUtil;
import net.maku.module.vo.AgCategoryVO;
import net.maku.module.vo.AgContentCombined;
import net.maku.system.dao.SysUserRoleDao;
import org.apache.http.impl.bootstrap.HttpServer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.stream.Collectors;

@Service
public class AgContentServiceImpl extends BaseServiceImpl<AgContentDao, AgContent> implements AgContentService {
    public static final String APP_ID = "ACyxhJKQ";
    public static final String APP_SECRET = "61ef7cfbac305c6b71d7b3038043526221d87138";
    private long fixedRate = 86400000;  // 默认间隔时间 24小时（单位：毫秒）
    private final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    private int contentId = 0;
    // 用于存储定时任务的引用，以便取消或管理
    private Map<Integer, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();

    public AgContentServiceImpl() {
        taskScheduler.setPoolSize(5); // 设置线程池大小
        taskScheduler.initialize();
    }

    @Autowired
    private AgContentDao agContentDao;

    @Resource
    private AgCategoryPermissionDao agCategoryPermissionDao;

    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    @Autowired
    private AgApproveService agApproveService;

    @Autowired
    private UrlReplaceUtil urlReplaceUtil;

    @Override
    public int deleteBatch(List<Integer> ids) {


        agContentDao.deleteBatch(ids);
        return 1;
    }

    @Override
    public PageResult<AgContentCombined> selectContent(Integer templateType, String title, Integer pageNum,
                                                       Integer pageSize, Integer id, Integer websiteId,
                                                       String approveState) throws Exception {
        Map param = new HashMap();
        long userId = SecurityUser.getUser().getId();
        List<String> roleNames = sysUserRoleDao.getRoleInfoList(userId);
        List<Long> categoryIds = agCategoryPermissionDao.getCategoryIdsByUserId(userId);

        // 查询所有满足条件的栏目
        if (categoryIds.size() <= 0 && !roleNames.contains("admin")) {
            //无数据权限
            return new PageResult<>(Collections.emptyList(), (long) 0);
        }

        if (roleNames.contains("admin")) {
            //管理员查询所有
            categoryIds = new ArrayList<>();
        }

        if (!StringUtils.isEmpty(approveState)) {
            //查询我的审批记录
            Map param1 = new HashMap();
            param1.put("businessType", "2");
            //param1.put("businessId", categoryVO.getId());
            param1.put("approveState", approveState);
            param1.put("userId", userId);
            if ("4".equals(approveState)) {
                param1.put("updater", userId);
            }
            List<AgApproveEntity> data3 = agApproveService.queryList(param1);
            if (CollectionUtils.isEmpty(data3)) {
                return new PageResult<>(Collections.emptyList(), (long) 0);
            }
            List<Integer> result = data3.stream()
                    .map(AgApproveEntity::getBusinessId) // 假设 AgApproveEntity 有一个 getName 方法
                    .collect(Collectors.toList());
            param.put("categoryIdsApprove", result);

        }

        // 计算分页偏移量
        int offset = (pageNum - 1) * pageSize;

        param.put("categoryIds", categoryIds);

        //param.put("categoryIds",categoryIds);
        if (templateType != null) {


            /*            if (templateType == 3 || templateType == 4 || templateType == 5) {*/
            List<AgContentCombined> linkList = agContentDao.selectLinkContent(templateType, title,
                    offset, pageSize, id, websiteId, param);
            //增加按钮权限
            buildContent(linkList, approveState, userId);

            int totals = agContentDao.countLinkContent(templateType, title, id, param);
            int totalPage = (int) Math.ceil((double) totals / pageSize);
            PageResult<AgContentCombined> page = new PageResult<>(linkList, totals);
            return page;
            /*} else {
                List<AgContentCombined> contentCombineds = agContentDao.selectContentWithOffset(templateType,
                        title, offset, pageSize, id, websiteId, param);

                buildContent(contentCombineds, approveState, userId);
                // 查询总记录数
                int total = agContentDao.countContent(templateType, title, id, param);

                // 计算总页数
                int totalPages = (int) Math.ceil((double) total / pageSize);

                // 构建分页结果，使用现有的构造方法
                PageResult<AgContentCombined> pageResult = new PageResult<>(contentCombineds, total);

                return pageResult;
            }*/
        } else {

            List<AgContentCombined> contentCombineds = agContentDao.selectContentWithOffset(templateType, title, offset, pageSize, id, websiteId, param);

            buildContent(contentCombineds, approveState, userId);
            // 查询总记录数
            int total = agContentDao.countContent(templateType, title, id,websiteId, param);

            // 计算总页数
            int totalPages = (int) Math.ceil((double) total / pageSize);

            // 构建分页结果，使用现有的构造方法
            PageResult<AgContentCombined> pageResult = new PageResult<>(contentCombineds, total);

            return pageResult;
        }
    }

    private void buildContent(List<AgContentCombined> linkList, String approveState, long userId) {
        long executor = SecurityUser.getUser().getId();
        if (!CollectionUtils.isEmpty(linkList)) {

            linkList.forEach(e -> {
                Map param = new HashMap();
                param.put("categoryId", e.getCategoryId());

                //Map param = new HashMap();
                param.put("userId", executor);
                List<AgCategoryPermission> data1 = agCategoryPermissionDao.queryList(param);
                if (!CollectionUtils.isEmpty(data1)) {
                    e.setAgCategoryPermission(data1.get(0));
                } else {
                    e.setAgCategoryPermission(null);
                }

                Map param1 = new HashMap();
                param1.put("businessType", "2");
                //param1.put("businessId", categoryVO.getId());
                param1.put("approveState", approveState);
                param1.put("userId", userId);
                if ("4".equals(approveState)) {
                    param1.put("updater", userId);
                }
                List<AgApproveEntity> data3 = agApproveService.queryList(param1);
                if (!CollectionUtils.isEmpty(data3)) {
                    e.setAgApprove(data3.get(0));
                } else {
                    e.setAgApprove(null);
                }
            });

        }

    }

    @Override
    public void updateFixedRate(long interval) {
        this.fixedRate = interval;
    }

    @Override
    @Transactional
    public int saveContent(AgContentCombined agContentCombined) {
        int result = saveOrUpdateContent(agContentCombined);
        if (result > 0) {
            // 定时发布
            if (agContentCombined.getPublishTime() != null) {
                schedulePublish(agContentCombined.getId(), agContentCombined.getPublishTime(), "0");
            }

            // 定时撤销
            if (agContentCombined.getCancellationTime() != null) {
                schedulePublish(agContentCombined.getId(), agContentCombined.getCancellationTime(), "1");
            }
        }
        return result;
    }

    @Override
    @Transactional
    public int updateContent(AgContentCombined agContentCombined) {
        // 更新主表内容
        AgContent agContent = new AgContent();
        populateAgContent(agContent, agContentCombined);
        float newSortValue = getNewSortValue();
        agContent.setSort(agContentCombined.getSort());
        agContent.setApproveState("1");
        agContent.setApproveType("2");
        int contentUpdated = agContentDao.updateById(agContent);

        if (contentUpdated > 0) {
            // 更新链接表内容（如果需要）
            AgContentLink link = new AgContentLink();
            link.setContentId(agContent.getId());
            link.setLinkTitle(agContentCombined.getLinkTitle());
            link.setUpdateTime(LocalDateTime.now());

            AgContentLink existingLink = agContentDao.selectLinkByContentId(agContent.getId());
            if (existingLink != null) {
                agContentDao.updateLink(link);
            } else {
                link.setCreateTime(LocalDateTime.now());
                agContentDao.insertLink(link);
            }


            // ===== 新增：处理定时任务 =====
            handleSchedule(agContentCombined);
        }

        return contentUpdated;
    }

    private void cancelScheduledTask(String key) {
        ScheduledFuture<?> existingTask = scheduledTasks.remove(key);
        if (existingTask != null) {
            existingTask.cancel(false);
        }
    }

    /**
     * 根据 publishTime / cancellationTime 设置定时任务
     */
    private void handleSchedule(AgContentCombined agContentCombined) {
        Integer contentId = agContentCombined.getId();

        // 先清理之前的任务
        cancelScheduledTask(contentId + "_publish");
        cancelScheduledTask(contentId + "_cancel");

        // 定时发布
        if (agContentCombined.getPublishTime() != null) {
            schedulePublish(contentId, agContentCombined.getPublishTime(), "0");
        }

        // 定时撤销
        if (agContentCombined.getCancellationTime() != null) {
            schedulePublish(contentId, agContentCombined.getCancellationTime(), "1");
        }
    }

    public Map<String, Object> selectContentByIdWithPage(HttpServletRequest request, Integer id, Integer type, Integer webSiteId, int page, int pageSize) {
        int offset = (page - 1) * pageSize;

        List<AgContentCombined> list;
        if (type == 1) {
            list = agContentDao.selectContentById(id, webSiteId, offset, pageSize);
        } else {
            list = agContentDao.selectAllContentById(id, webSiteId, offset, pageSize);
        }

        // 使用工具类替换URL
        urlReplaceUtil.replaceImageUrlsContent(request,list);
        urlReplaceUtil.replaceContent(request,list);
        urlReplaceUtil.replaceHref(request,list);

        int total = agContentDao.countContentById(id, webSiteId);

        Map<String, Object> result = new HashMap<>();
        result.put("data", list);
        result.put("total", total);
        result.put("page", page);
        result.put("pageSize", pageSize);

        if (!list.isEmpty()) {
            result.put("templateType", list.get(0).getTemplateType());
        } else {
            result.put("templateType", null);
        }

        return result;
    }

    @Override
    public AgContentCombined queryById(Integer id) {
        return agContentDao.queryById(id);
    }

    @Override
    public AgContentCombined getSortIsOne(Integer id) {
        return agContentDao.getSortIsOne(id);
    }

    @Override
    public void updateStatusByContentId(AgContentCombined agContentCombined) {
        agContentDao.updateStatusByContentId(agContentCombined);
    }

    @Override
    public List<AgContentCombined> selectShowContent(Integer websiteId) {
        return agContentDao.selectShowContent(websiteId);
    }

    @Override
    public PageResult selectNotShowContent(Integer pageNum, Integer pageSize, Integer websiteId) {
        // 计算 offset
        int offset = (pageNum - 1) * pageSize;

        // 查询分页内容
        List<AgContentCombined> contentCombineds = agContentDao.selectNotShowContent(offset, pageSize, websiteId);

        // 查询总记录数
        int total = agContentDao.selectNotShowContentCount(websiteId);

        // 计算总页数
        int totalPages = (int) Math.ceil((double) total / pageSize);

        // 构建分页结果，使用现有的构造方法
        PageResult<AgContentCombined> pageResult = new PageResult<>(contentCombineds, total);

        return pageResult;
    }

    @Override
    public int updateShow(Integer id, Integer show) {
        return agContentDao.updateShow(id, show);

    }

    @Override
    public PageResult<AgContentCombined> searchFull(String text, Integer pageNum, Integer pageSize, Integer websiteId) {
        int offset = (pageNum - 1) * pageSize;

        // Step 1: 尝试使用 keyword 匹配
        List<AgContentCombined> keywordMatchList = agContentDao.searchByKeyword(text, offset, pageSize, websiteId);
        int keywordTotal = agContentDao.countByKeyword(text, websiteId);

        if (keywordTotal > 0) {
            return new PageResult<>(keywordMatchList, keywordTotal);
        }

        // Step 2: fallback 使用 content 和 link_title 匹配
        List<AgContentCombined> contentList = agContentDao.searchFull(text, offset, pageSize, websiteId);
        int total = agContentDao.countFullSearchResults(text);

        return new PageResult<>(contentList, total);
    }

    @Override
    public void insertLog(AgContentLogEntity agContentLogEntity) {
        agContentLogEntity.setUpdateTime(new Date());
        agContentDao.insertLog(agContentLogEntity);
    }

    @Override
    public PageResult<AgContentLogEntity> selectContentLogs(Integer type, Integer success, Integer pageNum, Integer pageSize) {
        int offset = (pageNum - 1) * pageSize;

        // 查询内容和链接
        List<AgContentLogEntity> contentList = agContentDao.selectContentLogs(type, success, offset, pageSize);

        // 获取总数
        int total = agContentDao.selectContentLogsCount(type, success);

        // 返回分页结果
        return new PageResult<>(contentList, total);
    }

    @Override
    public List<AgContentCombined> getHomeContent() {
        return agContentDao.getHomeContent();
    }

    @Override
    public List<AgContentCombined> getAnnouncement() {
        return agContentDao.getAnnouncement();
    }


    private int saveOrUpdateContent(AgContentCombined agContentCombined) {
        AgContent agContent = new AgContent();

        Integer id = agContentCombined.getCategoryId();
        if (id == 1902 || id == 1900) {
            if ("1".equals(agContentCombined.getIsHome())) {
                //这两个栏目id的内容可以上首页 同时最多可存在两个上首页的内容 并且一个栏目id最多1个上首页的内容
                agContentDao.setNotHome(id);
                agContent.setIsHome(agContentCombined.getIsHome());
            }
        }
        populateAgContent(agContent, agContentCombined);
        // 获取当前最小的 sort 值
        float newSortValue = getNewSortValue();
        agContent.setSort(agContentCombined.getSort());
        agContent.setApproveState("1");
        agContent.setApproveType("1");
        agContent.setIsAnnouncement(agContentCombined.getIsAnnouncement());
        agContent.setHref(agContentCombined.getHref());
        agContent.setCustomDate(agContentCombined.getCustomDate());
        // 检查内容是否存在
        AgContent existingContent = agContentDao.selectById(agContent.getId());
        int result;
        if (existingContent != null) {
            // 如果存在，执行更新操作
            UserDetail user = SecurityUser.getUser();
            AgContentLogEntity agContentLogEntity = new AgContentLogEntity();
            agContentLogEntity.setType(2);
            agContentLogEntity.setSuccess(1);
            agContentLogEntity.setUpdateTime(new Date());
            agContentLogEntity.setModuleName("内容管理-编辑-成功");
//            agContentLogEntity.setUserId(Math.toIntExact(user.getId()));
            agContentLogEntity.setUserId(10000);
            agContentDao.insertLog(agContentLogEntity);
            result = agContentDao.updateById(agContent);
        } else {
            // 如果不存在，执行插入操作
            UserDetail user = SecurityUser.getUser();
            AgContentLogEntity agContentLogEntity = new AgContentLogEntity();
            agContentLogEntity.setType(1);
            agContentLogEntity.setSuccess(1);
            agContentLogEntity.setUpdateTime(new Date());
            agContentLogEntity.setModuleName("内容管理-新增-成功");
//            agContentLogEntity.setUserId(Math.toIntExact(user.getId()));
            agContentLogEntity.setUserId(10000);
            agContentDao.insertLog(agContentLogEntity);
            result = agContentDao.insert(agContent);
        }

        AgContentLink link = new AgContentLink();
        link.setContentId(agContent.getId());
        link.setLinkTitle(agContentCombined.getLinkTitle());
//            link.setSort(agContentCombined.getSort());
        link.setCreateTime(LocalDateTime.now());
        link.setUpdateTime(LocalDateTime.now());

        // 假设 Link 的插入也需要更新逻辑
        AgContentLink existingLink = agContentDao.selectLinkByContentId(agContent.getId());
        if (existingLink != null) {
            agContentDao.updateLink(link);
        } else {
            agContentDao.insertLink(link);
        }


        agContentCombined.setId(agContent.getId()); // 更新传入对象的 ID
        return result;
    }

    private void populateAgContent(AgContent agContent, AgContentCombined agContentCombined) {
        agContent.setCategoryId(agContentCombined.getCategoryId());
        agContent.setId(agContentCombined.getId());
        agContent.setTitle(agContentCombined.getTitle());
        agContent.setContent(agContentCombined.getContent());
        agContent.setImageUrl(agContentCombined.getImageUrl());
        agContent.setCssStyle(agContentCombined.getCssStyle());
        agContent.setTemplateType(agContentCombined.getTemplateType());
        agContent.setSource(agContentCombined.getSource());
        agContent.setPublishTime(agContentCombined.getPublishTime());
        agContent.setStatus(agContentCombined.getStatus() == null ? 0 : agContentCombined.getStatus());
        agContent.setCreator(agContentCombined.getCreator());
        agContent.setUpdater(agContentCombined.getUpdater());
        agContent.setSort(agContentCombined.getSort());
        agContent.setIsShow(agContentCombined.getIsShow());
        agContent.setKeyword(agContentCombined.getKeyword());
    }

    private void schedulePublish(Integer contentId, LocalDateTime time, String type) {
        long delay = Duration.between(LocalDateTime.now(), time).toMillis();

        if (delay <= 0) {
            // 立即执行
            if ("0".equals(type)) {
                publishContent(contentId);
            } else {
                publishContentNotPublish(contentId);
            }
        } else {
            ScheduledFuture<?> task;
            if ("0".equals(type)) {
                task = taskScheduler.schedule(() -> publishContent(contentId),
                        new Date(System.currentTimeMillis() + delay));
                scheduledTasks.put(contentId, task);
            } else {
                task = taskScheduler.schedule(() -> publishContentNotPublish(contentId),
                        new Date(System.currentTimeMillis() + delay));
                scheduledTasks.put(contentId, task);
            }
        }
    }

    //设置为发布状态
    private void publishContent(int contentId) {
        AgContent agContent = agContentDao.selectById(contentId);
        if (agContent != null) {
            agContent.setStatus(1); // 假设 1 表示已发布状态
            agContentDao.updateById(agContent);
            scheduledTasks.remove(contentId);
        }
    }

    //设置为为发布状态
    private void publishContentNotPublish(int contentId) {
        AgContent agContent = agContentDao.selectById(contentId);
        if (agContent != null) {
            agContent.setStatus(0); // 假设 1 表示已发布状态
            agContentDao.updateById(agContent);
            scheduledTasks.remove(contentId);
        }
    }

    private float getNewSortValue() {
        // 获取当前最小的 sort 值
        Integer minSort = agContentDao.selectSortMax();
        double minSortValue = minSort != null ? minSort.doubleValue() : 0.0;

        // 判断如果最小值已经是0.1，减少0.01
        double newSortValue = (minSortValue == 0.1) ? minSortValue - 0.01 : minSortValue - 0.1;

        // 使用 float 类型并四舍五入，保留 2 位小数
        return (float) Math.round(newSortValue * 100) / 100;
    }
}
